/**
 * 
 */
package com.hfjyz.exam.service;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindException;
import org.springframework.web.multipart.MultipartFile;

import com.hfjyz.exam.dao.PaperDao;
import com.hfjyz.exam.dao.PaperDetailDao;
import com.hfjyz.exam.dao.PaperSectionDao;
import com.hfjyz.exam.dao.QuestionDao;
import com.hfjyz.exam.dao.QuestionOptionsDao;
import com.hfjyz.exam.model.Paper;
import com.hfjyz.exam.model.PaperDetail;
import com.hfjyz.exam.model.PaperSection;
import com.hfjyz.exam.model.Question;
import com.hfjyz.exam.model.QuestionOptions;
import com.hfjyz.exam.util.ValidatorUtil;

/**
 *
 */
public class LoadQuestionServiceImpl extends AbstractServiceImpl implements
		LoadQuestionService {
	private QuestionDao questionDao;
	private QuestionOptionsDao questionOptionsDao;
	private PaperDao paperDao;
	private PaperSectionDao paperSectionDao;
	private PaperDetailDao paperDetailDao;

	@Transactional(rollbackFor = { Exception.class })
	@Override
	public void analyzeQuestionInfo(HttpServletRequest request,
			MultipartFile multipartFile, BindException errors) throws Exception {
		HSSFWorkbook workbook = null;
		try {
			workbook = new HSSFWorkbook(multipartFile.getInputStream());
		} catch (FileNotFoundException e) {
			errors.reject("error.loadquestion", "failed loadquestion!");
			return;
		} catch (IOException e) {
			throw e;
		}
		// 获得指定的sheet
		HSSFSheet sheet = workbook.getSheetAt(0);
		// 获得sheet总行数
		int rowCount = sheet.getLastRowNum();
		if (rowCount < 8) {
		}

		// read for paper
		int rowIndex = 1;
		HSSFRow prow = sheet.getRow(rowIndex);
		Paper p = new Paper();
		p.setName(getCellStringValue(prow.getCell(0)));
		p.setStarttime(getCellDateValue(prow.getCell(1)));
		p.setEndtime(getCellDateValue(prow.getCell(2)));
		p.setDuration(getCellIntegerValue(prow.getCell(3)));
		Integer pscores = 0;

		// paper section
		rowIndex += 3;
		Map<Integer, PaperSection> pss = new HashMap<Integer, PaperSection>();
		for (; rowIndex <= rowCount; rowIndex++) {
			HSSFRow row = sheet.getRow(rowIndex);
			Integer c0 = getCellIntegerValue(row.getCell(0));
			if (c0 == null) {
				break;
			}
			PaperSection ps = new PaperSection();
			ps.setName(getCellStringValue(row.getCell(1)));
			ps.setRemark(getCellStringValue(row.getCell(2)));
			ps.setPerScore(getCellIntegerValue(row.getCell(3)));
			ps.setPaper(p);
			pss.put(c0, ps);
		}

		// question && paper detail
		rowIndex += 2;
		List<Question> qs = new ArrayList<Question>();
		List<PaperDetail> pds = new ArrayList<PaperDetail>();
		List<QuestionOptions> qos = new ArrayList<QuestionOptions>();

		int quesitonseq = 1;
		for (; rowIndex <= rowCount; rowIndex++) {
			HSSFRow row = sheet.getRow(rowIndex);
			if (null != row) {
				Question q = new Question();
				qs.add(q);

				PaperDetail pd = new PaperDetail();
				pds.add(pd);
				pd.setPaper(p);
				pd.setQuestion(q);
				Integer pdscore = getCellIntegerValue(row.getCell(3));
				pd.setScore(pdscore);
				pscores += pdscore;
				Integer pdps = getCellIntegerValue(row.getCell(1));
				pd.setPaperSection(pss.get(pdps));
				pd.setSeq(quesitonseq++);

				Integer qtype = getCellIntegerValue(row.getCell(0));
				String qname = getCellStringValue(row.getCell(2));
				q.setContent(qname);
				q.setQtype(qtype);
				int cellCount = row.getLastCellNum();
				if (qtype == 2 || qtype == 3) {
					for (int cellIndex = 4; cellIndex < cellCount - 1; cellIndex++) {
						String qoption = getCellStringValue(row
								.getCell(cellIndex));
						if (ValidatorUtil.isEmpty(qoption)) {
							break;
						}
						QuestionOptions qo = new QuestionOptions();
						qo.setQuestion(q);
						qos.add(qo);
						qo.setQoption(qoption);
						char alias = (char) ('A' + (cellIndex - 4));
						qo.setAlias(String.valueOf(alias));
					}
				}
				String qkey = getCellStringValue(row.getCell(cellCount - 1));
				if (qtype == 1) {
					q.setQkey(Integer.valueOf(qkey).intValue() == 1 ? "YES"
							: "NO");
				} else {
					q.setQkey((String) qkey);
				}
			}
		}
		p.setScores(pscores);

		questionDao.addAll(qs);
		questionOptionsDao.addAll(qos);
		paperDao.add(p);
		List<PaperSection> psss = new ArrayList<PaperSection>();
		psss.addAll(pss.values());
		paperSectionDao.addAll(psss);
		paperDetailDao.addAll(pds);
	}

	private Integer getCellIntegerValue(HSSFCell cell) {
		String strValue = new DataFormatter().formatCellValue(cell);
		if (ValidatorUtil.isEmpty(strValue)) {
			return null;
		}
		return Integer.valueOf(strValue);
	}

	private Date getCellDateValue(HSSFCell cell) {
		if (cell == null || !HSSFDateUtil.isCellDateFormatted(cell)) {
			return null;
		}
		return HSSFDateUtil.getJavaDate(cell.getNumericCellValue());
	}

	private String getCellStringValue(HSSFCell cell) {
		return new DataFormatter().formatCellValue(cell);
	}

	/**
	 * @return the QuestionDao
	 */
	public QuestionDao getQuestionDao() {
		return questionDao;
	}

	/**
	 * @param QuestionDao
	 *            the QuestionDao to set
	 */
	public void setQuestionDao(QuestionDao questionDao) {
		this.questionDao = questionDao;
	}

	/**
	 * @return the questionOptionsDao
	 */
	public QuestionOptionsDao getQuestionOptionsDao() {
		return questionOptionsDao;
	}

	/**
	 * @param questionOptionsDao
	 *            the questionOptionsDao to set
	 */
	public void setQuestionOptionsDao(QuestionOptionsDao questionOptionsDao) {
		this.questionOptionsDao = questionOptionsDao;
	}

	/**
	 * @return the paperDetailDao
	 */
	public PaperDetailDao getPaperDetailDao() {
		return paperDetailDao;
	}

	/**
	 * @param paperDetailDao
	 *            the paperDetailDao to set
	 */
	public void setPaperDetailDao(PaperDetailDao paperDetailDao) {
		this.paperDetailDao = paperDetailDao;
	}

	/**
	 * @return the paperDao
	 */
	public PaperDao getPaperDao() {
		return paperDao;
	}

	/**
	 * @param paperDao
	 *            the paperDao to set
	 */
	public void setPaperDao(PaperDao paperDao) {
		this.paperDao = paperDao;
	}

	/**
	 * @return the paperSectionDao
	 */
	public PaperSectionDao getPaperSectionDao() {
		return paperSectionDao;
	}

	/**
	 * @param paperSectionDao
	 *            the paperSectionDao to set
	 */
	public void setPaperSectionDao(PaperSectionDao paperSectionDao) {
		this.paperSectionDao = paperSectionDao;
	}
}
